package net.sk.china.city.talk.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import net.sk.china.city.talk.constants.Constants;
import net.sk.china.city.talk.model.system.SystemAttachment;
import net.sk.china.city.talk.response.CloudResponse;
import net.sk.china.city.talk.response.FileResultResponse;
import net.sk.china.city.talk.service.UploadService;
import net.sk.china.city.talk.service.system.SystemAttachmentService;
import net.sk.china.city.talk.service.system.SystemConfigService;
import net.sk.china.city.talk.service.upload.CosService;
import net.sk.china.city.talk.service.upload.OssService;
import net.sk.china.city.talk.service.upload.QiNiuService;
import net.sk.china.common.config.TalkConfig;
import net.sk.china.common.exception.TalkException;
import net.sk.china.common.response.UploadCommonResponse;
import net.sk.china.common.utils.DateUtil;
import net.sk.china.common.utils.TalkUtil;
import net.sk.china.common.utils.UploadUtil;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * UploadServiceImpl 接口实现
 * +----------------------------------------------------------------------
 * | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2018-2024 聊来All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 * +----------------------------------------------------------------------
 * | @Author: 聊来 <18970881148@qq.com>
 * +----------------------------------------------------------------------
 * | DateTime: 2024/6/2 17:16
 * +----------------------------------------------------------------------
 */

@Service
public class UploadServiceImpl implements UploadService {

    private static final Logger logger = LoggerFactory.getLogger(UploadServiceImpl.class);

    private final SystemConfigService systemConfigService;

    private final SystemAttachmentService systemAttachmentService;

    private final TalkConfig talkConfig;

    private final QiNiuService qiNiuService;

    private final OssService ossService;

    private final CosService cosService;

    public UploadServiceImpl(SystemConfigService systemConfigService, SystemAttachmentService systemAttachmentService, TalkConfig talkConfig, QiNiuService qiNiuService, OssService ossService, CosService cosService) {
        this.systemConfigService = systemConfigService;
        this.systemAttachmentService = systemAttachmentService;
        this.talkConfig = talkConfig;
        this.qiNiuService = qiNiuService;
        this.ossService = ossService;
        this.cosService = cosService;
    }

    public static final int NUM_NINETY_NINE = 99;

    /**
     * 图片上传
     * @param multipartFile 文件
     * @param model 模块 用户user,商品product,微信wechat,news文章
     * @param pid 分类ID 0编辑器,1商品图片,2拼团图片,3砍价图片,4秒杀图片,5文章图片,6组合数据图,7前台用户
     * @return {@code FileResultResponse}
     * @throws Exception
     */
    @Override
    public FileResultResponse imageUpload(MultipartFile multipartFile, String model, Integer pid) throws Exception {
        if (null == multipartFile || multipartFile.isEmpty()) {
            throw new TalkException("上传的文件对象不存在...");
        }
        String rootPath = (systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + "/").replace(" ", "").replace("//", "/");
        UploadUtil.setModelPath(model);
        String modelPath = "public/" + model + "/";
        String extStr = systemConfigService.getValueByKey(Constants.UPLOAD_IMAGE_EXT_STR_CONFIG_KEY);
        int size = Integer.parseInt(systemConfigService.getValueByKey(Constants.UPLOAD_IMAGE_MAX_SIZE_CONFIG_KEY));
        String type = Constants.UPLOAD_TYPE_IMAGE + "/";

        UploadCommonResponse uploadCommonResponse = new UploadCommonResponse();
        uploadCommonResponse.setRootPath(rootPath);
        uploadCommonResponse.setModelPath(modelPath);
        uploadCommonResponse.setExtStr(extStr);
        uploadCommonResponse.setSize(size);
        uploadCommonResponse.setType(type);


        // 文件名
        String fileName = multipartFile.getOriginalFilename();
        // 文件后缀名
        String extName = FilenameUtils.getExtension(fileName);
        if (StrUtil.isEmpty(extName)) {
            throw new RuntimeException("文件类型未定义不能上传...");
        }

        if (fileName.length() > NUM_NINETY_NINE) {
            fileName = StrUtil.subPre(fileName, 90).concat(".").concat(extName);
        }

        // 文件大小验证
        // 文件分隔符转化为当前系统的格式
        float fileSize = (float)multipartFile.getSize() / 1024 / 1024;
        String fs = String.format("%.2f", fileSize);
        if( fileSize > uploadCommonResponse.getSize()){
            throw new TalkException("最大允许上传" + uploadCommonResponse.getSize() + " MB的文件, 当前文件大小为 " + fs + " MB");
        }

        // 判断文件的后缀名是否符合规则
        if (StrUtil.isNotEmpty(uploadCommonResponse.getExtStr())) {
            // 切割文件扩展名
            List<String> extensionList = TalkUtil.stringToArrayStr(uploadCommonResponse.getExtStr());
            if (extensionList.size() > 0) {
                //判断
                if (!extensionList.contains(extName)) {
                    throw new TalkException("上传文件的类型只能是：" + uploadCommonResponse.getExtStr());
                }
            } else {
                throw new TalkException("上传文件的类型只能是：" + uploadCommonResponse.getExtStr());
            }
        }

        // 变更文件名
        String newFileName = UploadUtil.fileName(extName);
        // 创建目标文件的名称，规则：  子目录/年/月/日.后缀名
        // 文件分隔符转化为当前系统的格式
        String webPath = uploadCommonResponse.getType() + uploadCommonResponse.getModelPath() + DateUtil.localDateTimeToString(DateUtil.getNowTime(), Constants.DATE_FORMAT_DATE).replace("-", "/") + "/";
        String destPath = FilenameUtils.separatorsToSystem(uploadCommonResponse.getRootPath() + webPath) + newFileName;

        // 拼装返回的数据
        FileResultResponse resultFile = new FileResultResponse();
        resultFile.setFileSize(multipartFile.getSize());
        resultFile.setFileName(fileName);
        resultFile.setExtName(extName);
        resultFile.setServerPath(webPath + newFileName);
        resultFile.setUrl(systemConfigService.getValueByKey(Constants.UPLOAD_FILE_LOCAL_URL) + "/" + webPath + newFileName);
        resultFile.setType(multipartFile.getContentType());

        // 图片上传类型 1本地 2七牛云 3OSS 4COS 5上传到指定服务器, 默认本地
        String uploadType = systemConfigService.getValueByKey("uploadType");
        int uploadTypeInt = StrUtil.isNotBlank(uploadType) ? Integer.parseInt(uploadType) : 1;

        SystemAttachment systemAttachment = new SystemAttachment();
        systemAttachment.setName(resultFile.getFileName());
        systemAttachment.setAttDir(webPath + newFileName);
        systemAttachment.setSattDir(resultFile.getUrl());
        systemAttachment.setAttSize(resultFile.getFileSize().toString());
        systemAttachment.setAttType(resultFile.getType());
        // 图片上传类型 1本地 2七牛云 3OSS 4COS 5指定服务器存放, 默认本地
        systemAttachment.setImageType(uploadTypeInt);
        systemAttachment.setPid(pid);

        resultFile.setType(resultFile.getType().replace("image/", ""));

        String pre;
        CloudResponse cloud = new CloudResponse();
        // 创建文件夹
        File file = UploadUtil.createFile(destPath);
        // 上传文件
        multipartFile.transferTo(file);
        switch (uploadTypeInt) {
            case 1:
                // 图片大于1M（1024 * 1024） 进行压缩处理
                long s = 1048576L;
                if (multipartFile.getSize() >= s) { zipImageFile(file); }

                // undertow 在 linux 系统中 上传文件至 nginx 静态服务器后发现 group 和 institution 没有读权限解决方案
                setFilePermission(destPath);

                break;
            case 2:
                systemAttachment.setImageType(2);
                pre = "qn";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));

                try {
                    // 构造一个带指定Zone对象的配置类, 默认华东
                    Configuration cfg = new Configuration(Region.huadong());
                    if(cloud.getRegion().equals(Constants.CLOUD_HUA_BEI)){
                        cfg = new Configuration(Region.huabei());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_HUA_NAN)){
                        cfg = new Configuration(Region.huanan());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_BEI_MEI)){
                        cfg = new Configuration(Region.beimei());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_DONG_NAN_YA)){
                        cfg = new Configuration(Region.xinjiapo());
                    }

                    // 其他参数参考类注释
                    UploadManager uploadManager = new UploadManager(cfg);
                    // 生成上传凭证，然后准备上传
                    Auth auth = Auth.create(cloud.getAccessKey(), cloud.getSecretKey());
                    String upToken = auth.uploadToken(cloud.getBucketName());

                    String webPathQn = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.qCloud.id " + systemAttachment.getAttId());
//                    qiNiuService.uploadFile(uploadManager, cloudVo, upToken,
//                            systemAttachment.getSattDir(), webPathQn + "/" + systemAttachment.getSattDir(), systemAttachment.getAttId());   //异步处理
                    qiNiuService.uploadFile(uploadManager, cloud, upToken, systemAttachment.getSattDir(), webPathQn + "/" + systemAttachment.getSattDir(), file);   //异步处理
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.qCloud.fail " + e.getMessage());
                }
                break;
            case 3:
                systemAttachment.setImageType(3);
                pre = "al";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));
                try {
                    String webPathAl = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.oss.id " + systemAttachment.getAttId());
                    ossService.upload(cloud, systemAttachment.getSattDir(),  webPathAl + "/" + systemAttachment.getSattDir(), file);
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.oss fail " + e.getMessage());
                }
                break;
            case 4:
                systemAttachment.setImageType(4);
                pre = "tx";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));
                // 1 初始化用户身份信息(secretId, secretKey)
                COSCredentials cred = new BasicCOSCredentials(cloud.getAccessKey(), cloud.getSecretKey());
                // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
                ClientConfig clientConfig = new ClientConfig(new com.qcloud.cos.region.Region(cloud.getRegion()));
                // 3 生成 cos 客户端。
                COSClient cosClient = new COSClient(cred, clientConfig);

                try {
                    String webPathTx = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.cos.id " + systemAttachment.getAttId());
                    cosService.uploadFile(cloud, systemAttachment.getSattDir(), webPathTx + "/" + systemAttachment.getSattDir(), systemAttachment.getAttId(), cosClient);
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.cos.fail " + e.getMessage());
                } finally {
                    cosClient.shutdown();
                }
                break;
            case 5:
                JSch jsch = new JSch();
                Session session = jsch.getSession("root","172.17.100.171", 22);
                session.setPassword("Pxszww@123");
                session.setConfig("StrictHostKeyChecking", "no");
                session.connect();

                ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
                channelSftp.connect();
                // 如果目录不存在则创建目录
                String path = "/cloud/image/" + DateUtil.localDateTimeToString(DateUtil.getNowTime(), Constants.DATE_FORMAT_DATE) + "/";
                try {
                    channelSftp.ls(systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path);
                } catch (SftpException e) {
                    channelSftp.mkdir(systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path);
                }
                channelSftp.put(multipartFile.getInputStream(), systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path + newFileName);
                resultFile.setServerPath(path + newFileName);
                resultFile.setUrl(systemConfigService.getValueByKey(Constants.UPLOAD_FILE_LOCAL_URL) + path + newFileName);
                channelSftp.disconnect();
                session.disconnect();
                break;
            default: throw new TalkException("未知上传类型");
        }

        systemAttachmentService.save(systemAttachment);
        resultFile.setId(systemAttachment.getAttId());

        return resultFile;
    }

    /**
     * 文件上传
     * @param multipartFile 文件
     * @param model 模块 用户user,商品product,微信wechat,news文章
     * @param pid 分类ID 0编辑器,1商品图片,2拼团图片,3砍价图片,4秒杀图片,5文章图片,6组合数据图,7前台用户
     * @return {@code FileResultResponse}
     * @throws Exception
     */
    @Override
    public FileResultResponse fileUpload(MultipartFile multipartFile, String model, Integer pid) throws Exception {
        if (null == multipartFile || multipartFile.isEmpty()) {
            throw new TalkException("上传的文件对象不存在...");
        }

        String rootPath = (systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + "/").replace(" ", "").replace("//", "/");
        UploadUtil.setModelPath(model);
        String modelPath = "public/" + model + "/";
        String extStr = systemConfigService.getValueByKey(Constants.UPLOAD_FILE_EXT_STR_CONFIG_KEY);
        int size = Integer.parseInt(systemConfigService.getValueByKey(Constants.UPLOAD_FILE_MAX_SIZE_CONFIG_KEY));
        String type = Constants.UPLOAD_TYPE_FILE + "/";

        UploadCommonResponse uploadCommonResponse = new UploadCommonResponse();
        uploadCommonResponse.setRootPath(rootPath);
        uploadCommonResponse.setModelPath(modelPath);
        uploadCommonResponse.setExtStr(extStr);
        uploadCommonResponse.setSize(size);
        uploadCommonResponse.setType(type);

        // 文件名
        String fileName = multipartFile.getOriginalFilename();
        // 文件后缀名
        String extName = FilenameUtils.getExtension(fileName);
        if (StrUtil.isEmpty(extName)) {
            throw new RuntimeException("文件类型未定义不能上传...");
        }

        if (fileName.length() > Constants.NUM_NINETY_NINE) {
            fileName = StrUtil.subPre(fileName, 90).concat(".").concat(extName);
        }

        //文件大小验证
        // 文件分隔符转化为当前系统的格式
        float fileSize = (float)multipartFile.getSize() / 1024 / 1024;
        String fs = String.format("%.2f", fileSize);
        if( fileSize > uploadCommonResponse.getSize()){
            throw new TalkException("最大允许上传" + uploadCommonResponse.getSize() + " MB的文件, 当前文件大小为 " + fs + " MB");
        }

        if (StrUtil.isNotEmpty(uploadCommonResponse.getExtStr())) {
            // 切割文件扩展名
            List<String> extensionList = TalkUtil.stringToArrayStr(uploadCommonResponse.getExtStr());

            if (extensionList.size() > 0) {
                //判断
                if (!extensionList.contains(extName)) {
                    throw new TalkException("上传文件的类型只能是：" + uploadCommonResponse.getExtStr());
                }
            } else {
                throw new TalkException("上传文件的类型只能是：" + uploadCommonResponse.getExtStr());
            }
        }

        // 变更文件名
        String newFileName = UploadUtil.fileName(extName);
        // 创建目标文件的名称，规则：  子目录/年/月/日.后缀名
        // 文件分隔符转化为当前系统的格式
        String webPath = uploadCommonResponse.getType() + uploadCommonResponse.getModelPath() + DateUtil.localDateTimeToString(DateUtil.getNowTime(), Constants.DATE_FORMAT_DATE).replace("-", "/") + "/";
        String destPath = FilenameUtils.separatorsToSystem(uploadCommonResponse.getRootPath() + webPath) + newFileName;

        // 拼装返回的数据
        FileResultResponse resultFile = new FileResultResponse();
        resultFile.setFileSize(multipartFile.getSize());
        resultFile.setFileName(fileName);
        resultFile.setExtName(extName);
        resultFile.setServerPath(webPath + newFileName);
        resultFile.setUrl(systemConfigService.getValueByKey(Constants.UPLOAD_FILE_LOCAL_URL) + "/" + webPath + newFileName);
        resultFile.setType(multipartFile.getContentType());

        // 图片上传类型 1本地 2七牛云 3OSS 4COS 5上传到指定服务器, 默认本地
        String uploadType = systemConfigService.getValueByKey("uploadType");
        int uploadTypeInt = StrUtil.isNotBlank(uploadType) ? Integer.parseInt(uploadType) : 1;

        SystemAttachment systemAttachment = new SystemAttachment();
        systemAttachment.setName(resultFile.getFileName());
        systemAttachment.setAttDir(webPath + newFileName);
        systemAttachment.setSattDir(resultFile.getUrl());
        systemAttachment.setAttSize(resultFile.getFileSize().toString());
        systemAttachment.setAttType(resultFile.getType());
        // 图片上传类型 1本地 2七牛云 3OSS 4COS 5指定服务器存放, 默认本地
        systemAttachment.setImageType(uploadTypeInt);
        systemAttachment.setPid(pid);

        String pre;
        CloudResponse cloud = new CloudResponse();
        // 创建文件夹
        File file = UploadUtil.createFile(destPath);
        // 上传文件
        multipartFile.transferTo(file);
        switch (uploadTypeInt) {
            case 1:
                String ext = extName.toLowerCase();
                if (ext.equals(Constants.FILE_EXT_FLV) || ext.equals(Constants.FILE_EXT_MP3) || ext.equals(Constants.FILE_EXT_MP4)) {
                    try {
                        Encoder encoder = new Encoder();
                        MultimediaInfo m = encoder.getInfo(file);
                        long duration = m.getDuration() / 1000;
                        resultFile.setDuration(duration);
                        systemAttachment.setDuration(duration);
                    } catch (Exception e) {
                        logger.info("获取音视频时长错误：" + e.getMessage());
                    }
                }

                // undertow 在 linux 系统中 上传文件至 nginx 静态服务器后发现 group 和 institution 没有读权限解决方案
                setFilePermission(destPath);

                break;
            case 2:
                systemAttachment.setImageType(2);
                pre = "qn";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));

                try {
                    // 构造一个带指定Zone对象的配置类, 默认华东
                    Configuration cfg = new Configuration(Region.huadong());
                    if(cloud.getRegion().equals(Constants.CLOUD_HUA_BEI)){
                        cfg = new Configuration(Region.huabei());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_HUA_NAN)){
                        cfg = new Configuration(Region.huanan());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_BEI_MEI)){
                        cfg = new Configuration(Region.beimei());
                    }
                    if(cloud.getRegion().equals(Constants.CLOUD_DONG_NAN_YA)){
                        cfg = new Configuration(Region.xinjiapo());
                    }

                    // 其他参数参考类注释
                    UploadManager uploadManager = new UploadManager(cfg);
                    // 生成上传凭证，然后准备上传
                    Auth auth = Auth.create(cloud.getAccessKey(), cloud.getSecretKey());
                    String upToken = auth.uploadToken(cloud.getBucketName());

                    String webPathQn = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.qCloud.id " + systemAttachment.getAttId());
//                    qiNiuService.uploadFile(uploadManager, cloudVo, upToken,
//                            systemAttachment.getSattDir(), webPathQn + "/" + systemAttachment.getSattDir(), systemAttachment.getAttId());   //异步处理
                    qiNiuService.uploadFile(uploadManager, cloud, upToken, systemAttachment.getSattDir(), webPathQn + "/" + systemAttachment.getSattDir(), file);   //异步处理
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.qCloud.fail " + e.getMessage());
                }
                break;
            case 3:
                systemAttachment.setImageType(3);
                pre = "al";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));
                try {
                    String webPathAl = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.oss.id " + systemAttachment.getAttId());
                    ossService.upload(cloud, systemAttachment.getSattDir(),  webPathAl + "/" + systemAttachment.getSattDir(), file);
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.oss fail " + e.getMessage());
                }
                break;
            case 4:
                systemAttachment.setImageType(4);
                pre = "tx";
                cloud.setDomain(systemConfigService.getValueByKeyException(pre+"UploadUrl"));
                cloud.setAccessKey(systemConfigService.getValueByKeyException(pre+"AccessKey"));
                cloud.setSecretKey(systemConfigService.getValueByKeyException(pre+"SecretKey"));
                cloud.setBucketName(systemConfigService.getValueByKeyException(pre+"StorageName"));
                cloud.setRegion(systemConfigService.getValueByKeyException(pre+"StorageRegion"));
                // 1 初始化用户身份信息(secretId, secretKey)
                COSCredentials cred = new BasicCOSCredentials(cloud.getAccessKey(), cloud.getSecretKey());
                // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
                ClientConfig clientConfig = new ClientConfig(new com.qcloud.cos.region.Region(cloud.getRegion()));
                // 3 生成 cos 客户端。
                COSClient cosClient = new COSClient(cred, clientConfig);

                try {
                    String webPathTx = talkConfig.getUploadPath();
                    logger.info("AsyncServiceImpl.cos.id " + systemAttachment.getAttId());
                    cosService.uploadFile(cloud, systemAttachment.getSattDir(), webPathTx + "/" + systemAttachment.getSattDir(), systemAttachment.getAttId(), cosClient);
                } catch (Exception e){
                    logger.error("AsyncServiceImpl.cos.fail " + e.getMessage());
                } finally {
                    cosClient.shutdown();
                }
                break;
            case 5:
                JSch jsch = new JSch();
                Session session = jsch.getSession("root","172.17.100.171", 22);
                session.setPassword("Pxszww@123");
                session.setConfig("StrictHostKeyChecking", "no");
                session.connect();

                ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
                channelSftp.connect();
                // 如果目录不存在则创建目录
                String path = "/cloud/file/" + DateUtil.localDateTimeToString(DateUtil.getNowTime(), Constants.DATE_FORMAT_DATE) + "/";
                try {
                    channelSftp.ls(systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path);
                } catch (SftpException e) {
                    channelSftp.mkdir(systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path);
                }
                channelSftp.put(multipartFile.getInputStream(), systemConfigService.getValueByKey(Constants.UPLOAD_ROOT_PATH_CONFIG_KEY) + path + newFileName);
                resultFile.setServerPath(path + newFileName);
                resultFile.setUrl(systemConfigService.getValueByKey(Constants.UPLOAD_FILE_LOCAL_URL) + path + newFileName);
                channelSftp.disconnect();
                session.disconnect();
                break;
            default: throw new TalkException("未知上传类型");
        }
        systemAttachmentService.save(systemAttachment);
        resultFile.setId(systemAttachment.getAttId());

        return resultFile;
    }

    /**
     * 设置上传文件可读权限
     * undertow 在 linux 系统中 上传文件至 nginx 静态服务器后发现 group 和 institution 没有读权限解决方案
     * @param destPath 目标文件路径
     */
    private void setFilePermission(String destPath) throws IOException {
        String os = System.getProperty("os.name");
        String windows = "windows";
        if (os != null && !os.toLowerCase().startsWith(windows)) {
            Set<PosixFilePermission> permission = new HashSet<>();
            permission.add(PosixFilePermission.OWNER_READ);
            permission.add(PosixFilePermission.OWNER_WRITE);
            permission.add(PosixFilePermission.GROUP_READ);
            permission.add(PosixFilePermission.OTHERS_READ);
            Files.setPosixFilePermissions(Paths.get(destPath), permission);
        }

    }


    /**
     * 压缩图片
     * @param file 图片的服务器路径
     */
    private void zipImageFile(File file) {
        if (ObjectUtil.isNull(file)) { logger.info("图片不存在，无法进行压缩操作"); return; }
        try {
            Image scrFile = ImageIO.read(file);
            int width = scrFile.getWidth(null);
            int height = scrFile.getHeight(null);
            width = (int) (width * 0.75);
            height = (int) (height * 0.75);
            BufferedImage tag = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
            // 按照指定宽、高无损压缩
            tag.getGraphics().drawImage(scrFile.getScaledInstance(width, height, Image.SCALE_SMOOTH),0,0,null);

            // 压缩之后临时存放位置
            FileOutputStream out = new FileOutputStream(file);

            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

            encoder.encode(tag);
            out.close();
        } catch (Exception e) {
            logger.info("图片压缩异常", e);
        }
    }
}
